package com.qture.Demo;
/*
    类的内部成员之五：内部类
        1. Java中允许将一个类A声明在一个类B中，则类A就是内部类，类B为外部类。

        2. 内部类的分类：成员内部类 vs 局部内部类（方法内、代码块内、构造器内）

        3. 成员内部类：
            一方面：作为外部类的成员；
                > 调用外部类的结构
                > 可以被static修饰
                > 可以被4种不同的权限修饰
            另一方面：作为一个类。
                > 类内可以定义属性、方法、构造器等（包括内部类里还可以再定义内部类）
                > 可以被final修饰，表示此类不能被继承，言外之意，不使用final，就可以被继承。
                > 可以被abstract修饰

        4. 使用内部类关注以下3个问题：
            4.1 如何实例化成员内部类的对象
            4.2 如何在成员内部类中区分调用外部类的结构
            4.3 开发中局部内部类的使用 详见<InnerClassTest02>
        
        5.匿名内部类 详见<AnonymousInnerClassTest01>

*/
public class InnerClassTest01 {
    public static void main(String[] args) {

        /* 4.1 如何实例化成员内部类的对象 */
        //创建Dog类的实例（静态的成员内部类）
        Person.Dog dog = new Person.Dog();
        dog.show();

        //创建Bird类的实例（非静态成员内部类）
//        Person.Bird bird = new Person.Bird(); //错误的写法：因为Bird为非静态成员内部类，需要先拿到外部类Person的实例
        Person p = new Person();
        Person.Bird bird = p.new Bird();
        bird.sing();

        /* 4.2 如何在成员内部类中区分调用外部类的结构 */
        bird.display("喜鹊");
    }
}

class Person{

    String name = "小明";
    int age;

    public void eat(){
        System.out.println("人，吃饭");
    }

    //静态成员内部类
    static class Dog{
        String name;
        int age;

        public Dog(){}

        public void show(){
            System.out.println("卡拉是一条狗");
        }
    }
    //非静态成员内部类
    class Bird{
        String name = "杜鹃";

        public Bird(){}

        public void sing(){
            System.out.println("我是一只小小鸟");
            Person.this.eat();  //调用外部类的非静态属性
        }

        public void display(String name){
            System.out.println(name);               //方法的形参
            System.out.println(this.name);          //内部类Bird的属性
            System.out.println(Person.this.name);   //外部类Person的属性
        }
    }

    public void method(){
        //局部内部类（方法内）
        class AA{}
    }

    {
        //局部内部类（代码块内）
        class BB{}
    }

    public Person(){
        //局部内部类（构造器内）
        class CC{}
    }

}
